﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using QCM.Contract1;

namespace WcfServiceLibraryPbMetaData
{
    // REMARQUE : si vous modifiez le nom de classe « Service1 » ici, vous devez également mettre à jour la référence à « Service1 » dans App.config.
    public class Service1 : IContractContract
    {

        int nbAppel;
        public int NbAppel
        {
            get { return this.nbAppel; }
            set { this.nbAppel = value; }
        }

        static int nbInstance;
        public static int NbInstance
        {
            get { return nbInstance; }
            set { nbInstance = value; }
        }

        SqlCommand cmd;
        SqlConnection cnx;

        public Service1()
        {
            NbAppel = 0;
            NbInstance++;
            //            GC.Collect();
            try
            {

                cnx = new SqlConnection(WcfServiceLibraryPbMetaData.Properties.Settings.Default.DBConn);

                cmd = new SqlCommand();
                cmd.CommandText = "GetCategories";
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Connection = cnx;
            }
            catch (Exception e)
            {
                GenericFaultException gfe = new GenericFaultException();
                gfe.code = "Unknown Type";
                gfe.message = e.Message;
                gfe.reason = "Unknown reason";
                throw new System.ServiceModel.FaultException<GenericFaultException>(gfe);
            }
        }

        #region ICategorie Membres

        public List<Categorie> GetCategories()
        {
            NbAppel++;
            List<Categorie> categories = new List<Categorie>();
            try
            {
                cmd.Connection.Open();
                using (SqlDataReader sdr = cmd.ExecuteReader())
                {
                    while (sdr.Read())
                    {
                        categories.Add(new Categorie((int)sdr["Id"], (string)sdr["Nom"],
                            sdr["Mere"].GetType() == Type.GetType("System.DBNull") ? String.Empty : (string)sdr["Mere"]));
                    }
                }
            }
            catch (Exception e)
            {
                SQLFaultException sfe = new SQLFaultException();
                sfe.code = "PbDataBase";
                sfe.message = e.Message;
                sfe.reason = "Impossible de ce connecter à la base de données";
                throw new System.ServiceModel.FaultException<SQLFaultException>(sfe);
            }
            finally
            {
                if (cmd.Connection.State == ConnectionState.Open)
                    cmd.Connection.Close();
            }

            return categories;
        }

        #endregion

        #region IQuestionnaire Membres

        SqlCommand cmdGetQuestionnaire = null;
        public Questionnaire GetQuestionnaire(int idQuestionnaire)
        {
            NbAppel++;
            Questionnaire questionnaire = null;
            //Je recupere les informations globales du questionnaire
            if (cmdGetQuestionnaire == null)
            {
                cmdGetQuestionnaire = new SqlCommand();
                cmdGetQuestionnaire.CommandText = "GetQuestionnaire";
                cmdGetQuestionnaire.CommandType = CommandType.StoredProcedure;
                cmdGetQuestionnaire.Connection = cnx;
                cmdGetQuestionnaire.Parameters.Add(new SqlParameter("@IdQuestionnaire", SqlDbType.Int));
            }
            try
            {
                cmdGetQuestionnaire.Parameters["@IdQuestionnaire"].Value = idQuestionnaire;
                cmdGetQuestionnaire.Connection.Open();
                using (SqlDataReader sdr = cmdGetQuestionnaire.ExecuteReader())
                {
                    sdr.Read();
                    questionnaire = new Questionnaire((int)sdr["Id"], (string)sdr["Nom"], (string)sdr["Descriptif"], (int)sdr["nbQuestions"]);
                }
            }
            catch (Exception e)
            {
                SQLFaultException sfe = new SQLFaultException();
                sfe.code = "Questionnaire Introuvable";
                sfe.message = e.Message;
                sfe.reason = "Impossible de trouver le questionnaire n " + idQuestionnaire;
                throw new System.ServiceModel.FaultException<SQLFaultException>(sfe);
            }
            finally
            {
                if (cmdGetQuestionnaire.Connection.State == ConnectionState.Open)
                    cmdGetQuestionnaire.Connection.Close();
            }


            //J'appel GetQuestions et j'insert les resultats dans l'objet Questionnaire
            //questionnaire.Questions = GetQuestions(name);
            return questionnaire;
        }

        SqlCommand cmdShortQuestionnaires = null;
        public List<ShortQuestionnaire> GetQuestionnaires(int idCategorie)
        {
            NbAppel++;
            List<ShortQuestionnaire> titresQuestionnaires = new List<ShortQuestionnaire>();
            if (cmdShortQuestionnaires == null)
            {
                cmdShortQuestionnaires = new SqlCommand();
                cmdShortQuestionnaires.CommandText = "GetQuestionnaires";
                cmdShortQuestionnaires.CommandType = CommandType.StoredProcedure;
                cmdShortQuestionnaires.Connection = cnx;
                cmdShortQuestionnaires.Parameters.Add(new SqlParameter("@IdCategorie", SqlDbType.Int));
            }


            try
            {
                cmdShortQuestionnaires.Parameters["@IdCategorie"].Value = idCategorie;
                cmdShortQuestionnaires.Connection.Open();
                using (SqlDataReader sdr = cmdShortQuestionnaires.ExecuteReader())
                {
                    while (sdr.Read())
                    {
                        titresQuestionnaires.Add(new ShortQuestionnaire((int)sdr["Id"], (string)sdr["Nom"]));
                    }
                }
            }
            catch (Exception e)
            {
                SQLFaultException sfe = new SQLFaultException();
                sfe.code = "Questionnaires Introuvables";
                sfe.message = e.Message;
                sfe.reason = "Impossible de trouver les questionnaires de la catégorie " + idCategorie;
                throw new System.ServiceModel.FaultException<SQLFaultException>(sfe);
            }
            finally
            {
                if (cmdShortQuestionnaires.Connection.State == ConnectionState.Open)
                    cmdShortQuestionnaires.Connection.Close();
            }
            return titresQuestionnaires;
        }

        #endregion

        #region IQuestion Membres
        SqlCommand cmdGetQuestions = null;

        /// <summary>
        /// Retourne l'ensemble des questions et les reponses associées
        /// </summary>
        /// <param name="nomQuestionnaire">Nom du questionnaire dans lequel recuperer les questions</param>
        /// <returns></returns>
        public List<Question> GetQuestions(int idQuestionnaire)
        {
            List<Question> res = new List<Question>();
            if (cmdGetQuestions == null)
            {
                cmdGetQuestions = new SqlCommand();
                cmdGetQuestions.CommandText = "GetQuestionsForQuestionnaire";
                cmdGetQuestions.CommandType = CommandType.StoredProcedure;
                cmdGetQuestions.Connection = cnx;
                cmdGetQuestions.Parameters.Add(new SqlParameter("@IdQuestionnaire", SqlDbType.Int));
            }


            //Je recup les id des questions associées au questionnaire
            try
            {
                cmdGetQuestions.Parameters["@IdQuestionnaire"].Value = idQuestionnaire;
                cmdGetQuestions.Connection.Open();
                using (SqlDataReader sdr = cmdGetQuestions.ExecuteReader())
                {
                    //Pour chaque Id je crée un objet Question avec ses reponses
                    while (sdr.Read())
                    {
                        Question quest = new Question((string)sdr["Titre"], (int)sdr["Id"]);
                        res.Add(quest);
                    }
                }
            }
            catch (Exception e)
            {
                SQLFaultException sfe = new SQLFaultException();
                sfe.code = "Questions Introuvables";
                sfe.message = e.Message;
                sfe.reason = "Impossible de trouver les questions du questionnaire n" + idQuestionnaire;
                throw new System.ServiceModel.FaultException<SQLFaultException>(sfe);
            }
            finally
            {
                if (cmdGetQuestions.Connection.State == ConnectionState.Open)
                    cmdGetQuestions.Connection.Close();
            }
            foreach (Question quest in res)
            {
                quest.Reponses = this.getReponsesForQuestion(quest);
            }
            return res;
        }

        SqlCommand cmdGetRepForQuest = null;

        private List<Reponse> getReponsesForQuestion(Question quest)
        {
            List<Reponse> res = new List<Reponse>();
            if (cmdGetRepForQuest == null)
            {
                cmdGetRepForQuest = new SqlCommand();
                cmdGetRepForQuest.CommandText = "GetReponsesForQuestion ";
                cmdGetRepForQuest.CommandType = CommandType.StoredProcedure;
                cmdGetRepForQuest.Connection = cnx;
                cmdGetRepForQuest.Parameters.Add(new SqlParameter("@IdQuestion", SqlDbType.Int));
            }


            //Je recup les réponses associées à la question
            try
            {
                cmdGetRepForQuest.Parameters["@IdQuestion"].Value = quest.Id;
                cmdGetRepForQuest.Connection.Open();
                using (SqlDataReader sdr = cmdGetRepForQuest.ExecuteReader())
                {
                    //Pour chaque Id je crée un objet Question avec ses reponses
                    while (sdr.Read())
                    {
                        res.Add(new Reponse((string)sdr["Text"], (int)sdr["Valeur"]));
                    }
                }
            }
            catch (Exception e)
            {
                SQLFaultException sfe = new SQLFaultException();
                sfe.code = "Reponses Introuvables";
                sfe.message = e.Message;
                sfe.reason = "Impossible de trouver les réponses dde la question" + quest.Id;
                throw new System.ServiceModel.FaultException<SQLFaultException>(sfe);
            }
            finally
            {
                if (cmdGetRepForQuest.Connection.State == ConnectionState.Open)
                    cmdGetRepForQuest.Connection.Close();
            }

            return res;
        }

        #endregion

        #region Correction Members


        SqlCommand cmdCorrection = null;
        public int Correction(List<int> listReponses)
        {
            NbAppel++;
            if (cmdCorrection == null)
            {
                cmdCorrection = new SqlCommand();
                cmdCorrection.CommandText = "Correction";
                cmdCorrection.CommandType = CommandType.StoredProcedure;
                cmdCorrection.Connection = cnx;
                cmdCorrection.Parameters.Add(new SqlParameter("@IdReponses", SqlDbType.VarChar, 150));
            }
            Int32 note = 0;
            try
            {
                List<String> listReponsesAsString = new List<String>();
                foreach (int i in listReponses)
                {
                    listReponsesAsString.Add(i.ToString());
                }
                cmdCorrection.Parameters["@IdReponses"].Value = String.Join(", ", listReponsesAsString.ToArray());
                cmdCorrection.Connection.Open();
                using (SqlDataReader sdr = cmdCorrection.ExecuteReader())
                {
                    while (sdr.Read())
                    {
                        note = (Int32)sdr["note"];
                    }
                }
            }
            catch (Exception e)
            {
                SQLFaultException sfe = new SQLFaultException();
                sfe.code = "Correction impossible";
                sfe.message = e.Message;
                sfe.reason = "Impossible de corriger...";
                throw new System.ServiceModel.FaultException<SQLFaultException>(sfe);
            }
            finally
            {
                if (cmdCorrection.Connection.State == ConnectionState.Open)
                    cmdCorrection.Connection.Close();
            }
            return note;
        }

        public Boolean CorrectionSansScore(List<int> listReponses)
        {
            Int32 note = Correction(listReponses);
            if(note >= (listReponses.Count / 2))
                return true;
            return false;
        }

        public List<int> CorrectionAvecReponse(List<int> listReponses)
        {
            return new List<int>();
        }

        #endregion
    }
}
